package com.qy.common.base;

import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.viewbinding.ViewBinding;

import com.qy.common.mvp.IPresenter;
import com.qy.common.mvp.IView;
import com.qy.common.widget.MMLoading;

import org.simple.eventbus.EventBus;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * 基类
 * 复制版
 * initView();
 * initListener();
 *
 * @param <T>
 * @param <P>
 */

public abstract class BaseFragment<T extends ViewBinding, P extends IPresenter> extends Fragment implements IView {
    protected final String TAG = this.getClass().getSimpleName();
    protected Context mContext;

    protected T vb;
    protected P mPresenter;
    private MMLoading mmLoading;


    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mContext = getActivity();
        mPresenter = getPresenter();
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        Type superclass = getClass().getGenericSuperclass();
        Class<?> aClass = (Class<?>) ((ParameterizedType) superclass).getActualTypeArguments()[0];
        try {
            Method method = aClass.getDeclaredMethod("inflate", LayoutInflater.class, ViewGroup.class, boolean.class);
            vb = (T) method.invoke(null, getLayoutInflater(), container, false);
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
        pagerSetObjectForPosition();
        return vb.getRoot();

    }

    /**
     * 这个方法是为了工作页面ScrollView嵌套ViewPager，viewPager重新计算高度准备的
     */
    public void pagerSetObjectForPosition() {
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        if (useEventBus())//如果要使用eventbus请将此方法返回true
            EventBus.getDefault().register(this);//注册到事件主线
        initAny();
    }

    @Override
    public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
        super.onViewStateRestored(savedInstanceState);
        if (mPresenter == null) {
            mPresenter = getPresenter();
        }
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        this.vb = null;
        hideLoading();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mPresenter != null) mPresenter.onDestroy();//释放资源
        if (useEventBus())//如果要使用eventbus请将此方法返回true
            EventBus.getDefault().unregister(this);
        this.mPresenter = null;

    }

    /**
     * 是否使用eventBus,默认为不使用(false)，
     *
     * @return
     */
    protected boolean useEventBus() {
        return false;
    }

    protected abstract void initAny();

    protected abstract P getPresenter();

    /**
     * 此方法是让外部调用使fragment做一些操作的,比如说外部的activity想让fragment对象执行一些方法,
     * 建议在有多个需要让外界调用的方法时,统一传bundle,里面存一个what字段,来区分不同的方法,在setData
     * 方法中就可以switch做不同的操作,这样就可以用统一的入口方法做不同的事,和message同理
     * <p>
     * 使用此方法时请注意调用时fragment的生命周期,如果调用此setData方法时onActivityCreated
     * 还没执行,setData里调用presenter的方法时,是会报空的,因为dagger注入是在onActivityCreated
     * 方法中执行的,如果要做一些初始化操作,可以不必让外部调setData,在内部onActivityCreated中
     * 初始化就可以了
     *
     * @param data
     */
    public void setData(Object data) {

    }

    /**
     * 使用此方法时请注意调用时fragment的生命周期,如果调用此setData方法时onActivityCreated
     * 还没执行,setData里调用presenter的方法时,是会报空的,因为dagger注入是在onActivityCreated
     * 方法中执行的,如果要做一些初始化操作,可以不必让外部调setData,在内部onActivityCreated中
     * 初始化就可以了
     */
    public void setData() {

    }

    @Override
    public void showLoading(boolean cancelable) {
        if (mmLoading != null) mmLoading.dismiss();
        MMLoading.Builder builder = new MMLoading.Builder(mContext)
                .setMessage("加载中...")
                .setShowMessage(false)
                .setCancelable(cancelable)
                .setCancelOutside(false);
        mmLoading = builder.create();
        mmLoading.show();
    }

    @Override
    public void showLoading() {
        if (mmLoading != null) mmLoading.dismiss();
        if (mContext == null) return;
        MMLoading.Builder builder = new MMLoading.Builder(mContext)
                .setShowMessage(false)
                .setCancelable(true)
                .setCancelOutside(false);
        mmLoading = builder.create();
        mmLoading.show();
    }

    @Override
    public void hideLoading() {
        if (mmLoading != null && mmLoading.isShowing()) mmLoading.dismiss();

    }

}
